package ar.edu.utn.frba.disenio.aterrizar.busquedas;

import java.util.ArrayList;

import ar.edu.utn.frba.disenio.aterrizar.aerolineas.Aerolinea;
import ar.edu.utn.frba.disenio.aterrizar.aerolineas.*;
import ar.edu.utn.frba.disenio.aterrizar.excepciones.AsientoErroneoException;
import ar.edu.utn.frba.disenio.aterrizar.usuario.Usuario;

public class BusquedaObligatoria extends BusquedaFiltrada{
	
	Aerolinea adapter;
	CriterioBusqueda busqueda;
	Usuario usuario;
	private int cantMaxEscalas = 2;

	
	public BusquedaObligatoria(Aerolinea unaAerolinea, CriterioBusqueda unaBusqueda, Usuario unUsuario){
		this.adapter = unaAerolinea;
		this.busqueda = unaBusqueda;
		this.usuario = unUsuario;
		
	}
	
	public BusquedaObligatoria(){		
	}
			
	@Override
	public ArrayList<Vuelo> buscarVuelos(){
		
		ArrayList<Vuelo> disponibles = adapter.buscarVuelos(busqueda);
		
		if((this.busqueda.getEscalas() > 0) && (this.busqueda.getEscalas() <= this.cantMaxEscalas) )	{
			ArrayList<Vuelo> todosLosCandidatos = adapter.asientosTotales();
			ArrayList<Vuelo> candidatosOrigen = new ArrayList<Vuelo>();
			for(Vuelo unCandidatoOrigen : todosLosCandidatos )	{
				if((unCandidatoOrigen.origen.equals(this.busqueda.origen)) && (this.busqueda.fecha.fechaEstasEntre(unCandidatoOrigen.fechaSalida, unCandidatoOrigen.fechaLlegada))){
				VueloConEscalas vueloConEscalas = new VueloConEscalas();
				vueloConEscalas.agregarVuelo(unCandidatoOrigen);
				candidatosOrigen.add(vueloConEscalas);					
				}
			}
			ArrayList<Vuelo> candidatosEscalas = new ArrayList<Vuelo>();
			while(this.busqueda.decrementarEscalas() >= 0){
				for(Vuelo unCandidatoEscalas : candidatosOrigen){
					for(Vuelo unCandidatoAgregar : todosLosCandidatos){
						if((unCandidatoAgregar.origen.equals(unCandidatoEscalas.destino))&&(unCandidatoAgregar.fechaSalida.fechaEstasEntre(unCandidatoEscalas.fechaLlegada,unCandidatoAgregar.fechaLlegada))){
							VueloConEscalas vueloConEscalasAgregadas = new VueloConEscalas();
							for(Vuelo vuelosEnEscalas : unCandidatoEscalas.getVuelos()){
								vueloConEscalasAgregadas.agregarVuelo(vuelosEnEscalas);
							}
							vueloConEscalasAgregadas.agregarVuelo(unCandidatoAgregar);
							candidatosEscalas.add(vueloConEscalasAgregadas);
						}
					}
				}
				candidatosOrigen.clear();
				for(Vuelo nuevosCandidatosOrigen : candidatosEscalas){
					candidatosOrigen.add(nuevosCandidatosOrigen);
				}
				candidatosEscalas.clear();
			}
			for(Vuelo unVueloConEscalas: candidatosOrigen){
				if(unVueloConEscalas.destino.equals(this.busqueda.destino)){
					disponibles.add(unVueloConEscalas);
				}
			}			
		}
		ArrayList<Vuelo> retVal = new ArrayList<Vuelo>();
		
		for(Vuelo unVuelo : disponibles){
			unVuelo.aplicarRecargo(adapter.recargoAerolinea, usuario.getRecargoUsuario());
			if((unVuelo.esSuperOferta(unVuelo) && usuario.isSuperOfertas()) || !unVuelo.esSuperOferta(unVuelo)){
				retVal.add(unVuelo);	
			}			
        }  
		
		return retVal;
    }
	
	public Vuelo buscarVueloParticular(Aerolinea adapter, String codigo, Usuario usuario){
		
		ArrayList<Vuelo> asientosTotales = adapter.asientosTotales();
		
		for(Vuelo unVuelo : asientosTotales){
			if(unVuelo.codigo.equals(codigo)){
				unVuelo.aplicarRecargo(adapter.recargoAerolinea, usuario.getRecargoUsuario());
				return unVuelo;				 
			}			
        }  
		throw new AsientoErroneoException();
    }
	
}